import React, { PureComponent } from 'react';
import ProLayout from '@ant-design/pro-layout';
import { Form, Modal, Input, Spin } from 'antd';
import { connect } from 'dva';
import { router } from 'umi';
import Link from 'umi/link';
import Authorized, { reloadAuthorized } from '@/utils/Authorized';
import { getAuthorityFromRouter } from '@/utils/utils';
import styles from './BasicLayout.less';

import GlobalHeader from '@/components/GlobalHeader';
import NoMatch from '../pages/Exception/403';

class BasicLayout extends PureComponent {
  componentDidMount() {
    const { dispatch } = this.props;

    dispatch({
      type: 'global/getCurrentUser',
      payload: {
        callback: () => {
          this.initPage();
        }
      }
    });
  }

  initPage = () => {
    const { dispatch, location: { pathname }, route = {} } = this.props;
    const { routes = [] } = route;

    dispatch({
      type: 'global/validaterole',
      payload: {
        callback: () => {
          dispatch({ type: 'global/getCurrentUserUnit' });
          dispatch({ type: 'global/queryUserPermission' });
        }
      }
    });
    dispatch({
      type: 'global/queryUserMenus',
      payload: {
        callback: (list) => {
          this.path = undefined;
          const nCurrent = [];

          if (routes && routes.length > 0) {
            routes.forEach(child => {
              if (list.includes(child.path)) {
                if (child.authority) {
                  nCurrent.push(child.authority[0]);
                }
                if (!this.path) {
                  this.path = child.path;
                }
              }
              if (child.routes && child.routes.length > 0) {
                child.routes.forEach(sChild => {
                  if (list.includes(sChild.path)) {
                    if (sChild.authority) {
                      nCurrent.push(sChild.authority[0]);
                    }
                    if (!this.path) {
                      this.path = sChild.path;
                    }
                  }
                })
              }
            });
          }
          reloadAuthorized((current) => {
            if (typeof current === 'string') {
              return [current, ...nCurrent];
            } else if (Array.isArray(current)) {
              return [...current, ...nCurrent];
            } else {
              return nCurrent;
            }
          });
          if (pathname === '/' && this.path) {
            router.push(this.path);
          }
        }
      }
    });
  }

  componentWillReceiveProps(nextProps) {
    const { location = {} } = nextProps;
    const { pathname } = location;

    if (pathname === '/' && this.path) {
      router.push(this.path);
    }
  }

  componentWillUnmount() {
    this.props.dispatch({ type: `global/clear` });
  }

  handleMenuCollapse = (payload) => {
    const { dispatch } = this.props;

    if (dispatch) {
      dispatch({
        type: 'global/changeLayoutCollapsed',
        payload,
      });
    }
  }

  onOk = () => {
    const { dispatch, form, visible } = this.props;

    form.validateFields(visible === '首次登录需修改密码' ? ['newPassword', 'comfirm'] : ['oldPassword', 'newPassword', 'comfirm'], { force: true }, (err, values) => {
      if (!err) {
        const { oldPassword = '12345', newPassword } = values;

        dispatch({
          type: 'global/resetPassword',
          payload: { dispatch, oldPassword, newPassword },
        });
      }
    });
  }

  render() {
    const { dispatch, form, children, settings, location = { pathname: '/' }, currentUnit, userMenus, visible } = this.props;
    const { loading, ...extra } = this.props;

    const authorized = getAuthorityFromRouter(this.props.route.routes, location.pathname || '/') || {
      authority: undefined,
    };

    return (
      <ProLayout
        className={styles.basic_layout_wrapper}
        collapsed={false}
        disableMobile={true}
        headerRender={(headerProps) => {
          const { location, route = {} } = headerProps;
          const { routes = [] } = route;

          return (
            <GlobalHeader
              location={location}
              userMenus={userMenus}
              menus={routes.filter(item => !item.redirect && item.path)}
            />
          );
        }}
        onCollapse={this.handleMenuCollapse}
        // breadcrumbRender={(routers = []) => [
        //   {
        //     path: '/',
        //     breadcrumbName: formatMessage({
        //       id: 'menu.home',
        //       defaultMessage: 'Home',
        //     }),
        //   },
        //   ...routers,
        // ]}
        {...extra}
        {...settings}
      >
        <Spin
          className={styles.basic_spinning}
          spinning={
            !!loading.effects['global/getCurrentUser'] ||
            !!loading.effects['global/getCurrentUserUnit'] ||
            !!loading.effects['global/queryUserPermission'] ||
            !!loading.effects['global/queryUserMenus']
          }
        >
          {currentUnit && userMenus && userMenus.length > 0 &&
            <Authorized authority={authorized.authority} noMatch={<NoMatch />}>
              {children}
            </Authorized>
          }
        </Spin>
        <Modal
          centered
          destroyOnClose
          maskClosable={false}
          title={visible}
          visible={!!visible}
          wrapClassName={styles.common_modal_wrapper}
          width={560}
          onOk={this.onOk}
          onCancel={() => {
            dispatch({
              type: `global/changeState`,
              payload: {
                visible: undefined
              }
            })
          }}
        >
          <Edit form={form} fistLogin={visible === '首次登录需修改密码'} />
        </Modal>
      </ProLayout>
    );
  }
}

class Edit extends PureComponent {
  checkPassword = (rule, value, callback) => {
    if (!/(?=.*[a-zA-Z])(?=.*\d)(?=.*[#@!~%^&*])[a-zA-Z\d#@!~%^&*]{8,}/.test(value)) {
      callback('密码必须由8位以上字母+数字+符号(#@!~%^&*)混合组成');
    } else {
      callback();
    }
  }

  compareToFirstPassword = (rule, value, callback) => {
    const form = this.props.form;
    if (value && value !== form.getFieldValue('newPassword')) {
      callback('两次输入的密码不一致!');
    } else {
      callback();
    }
  };

  render() {
    const { form, fistLogin } = this.props;
    const { getFieldDecorator } = form;

    return (
      <Form layout='vertical'>
        {!fistLogin &&
          <Form.Item label='旧密码'>
            {getFieldDecorator('oldPassword', {
              initialValue: undefined,
              rules: [{ required: true, message: '该项为必填项' }]
            })(
              <Input placeholder='请输入旧密码' type='password' size='large' />
            )}
          </Form.Item>
        }
        <Form.Item label='新密码'>
          {getFieldDecorator('newPassword', {
            initialValue: undefined,
            rules: [
              { required: true, message: '该项为必填项' },
              { validator: this.checkPassword }
            ]
          })(
            <Input placeholder='请输入新密码' type='password' size='large' />
          )}
        </Form.Item>
        <Form.Item label='确认密码'>
          {getFieldDecorator('comfirm', {
            initialValue: undefined,
            rules: [
              { required: true, message: '该项为必填项' },
              { validator: this.compareToFirstPassword }
            ]
          })(
            <Input placeholder='请确认密码' type='password' size='large' />
          )}
        </Form.Item>
      </Form>
    );
  }
}

export default connect(({ loading, global, settings }) => ({ loading, collapsed: global.collapsed, currentUnit: global.currentUnit, userMenus: global.userMenus, visible: global.visible, settings }))(Form.create()(BasicLayout));
